package com.lzx.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.lzx.article.entity.Articles;
import com.lzx.article.entity.Collect;
import com.lzx.article.entity.GiveALike;
import com.lzx.article.entity.TwoSort;
import com.lzx.article.entity.vo.ArticleParams;
import com.lzx.article.enums.ArticleGrade;
import com.lzx.article.feign.UserClient;
import com.lzx.article.mapper.ArticlesMapper;
import com.lzx.article.mapper.CollectMapper;
import com.lzx.article.mapper.GiveALikeMapper;
import com.lzx.article.mapper.TwoSortMapper;
import com.lzx.article.service.ArticlesService;
import com.lzx.article.utils.TypeConversion;
import com.lzx.article.vo.ArticleVo;
import com.lzx.article.vo.ArticleVos;
import com.lzx.article.vo.User;
import com.lzx.common.utils.ExcelUtils;
import com.lzx.common.utils.R;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lzx
 * @since 2023-01-11
 */
@Service
public class ArticlesServiceImpl extends ServiceImpl<ArticlesMapper, Articles> implements ArticlesService {
    @Resource
    private ArticlesMapper articlesMapper;

    @Resource
    private UserClient userClient;

    @Resource
    private TwoSortMapper twoSortMapper;

    @Resource
    private GiveALikeMapper giveALikeMapper;

    @Resource
    private CollectMapper collectMapper;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    //获取文章列表
    @Override
    public R getArticleList(int current, int size) {
        Page<Articles> page = new Page<>(current, size);
        articlesMapper.selectPage(page, null);
        Map<String, Object> map = new HashMap<>();
        List<Articles> articlesList = page.getRecords();//当前页数据
        List<Articles> list = new ArrayList<>();
        for (Articles articles : articlesList) {
            User user = userClient.getUserinfoByIdToOtherServe(Long.valueOf(articles.getUserId()));
            //设置作者
            articles.setUser(user);
            //标签翻译
            List<String> ids = TypeConversion.stringToList(articles.getLabel());
            ArrayList<String> labels = new ArrayList<>();
            for (String id : ids) {
                TwoSort twoSort = twoSortMapper.selectById(id);
                labels.add(twoSort.getTagName());
            }
            articles.setLabels(labels);
            //内容等级翻译
            articles.setGradeTranslation(ArticleGrade.find(articles.getGrade()).getDesc());
            list.add(articles);
        }
        long total = page.getTotal();//总记录数
        map.put("list", list);
        map.put("total", total);
        return R.ok().data("map", map);
    }

    //发布文章
    @Transactional
    @Override
    public R saveArticle(ArticleVo articleVo) {
        Articles articles = new Articles();
        BeanUtils.copyProperties(articleVo, articles);
        Gson gson = new Gson();
        String json = gson.toJson(articleVo.getLabel(), List.class);
        articles.setLabel(json);
        articles.setCreateTime(new Date());
        articles.setLabelTranslation(StringUtils.join(labelTranslation(articles.getLabel()), ","));
        articlesMapper.insert(articles);
        //使用MQ来发送延迟消息 es同步
        rocketMQTemplate.syncSend("article-add-topic", MessageBuilder.withPayload(articles.getId()).build(), 3600000, 3);
        return R.ok().message("保存成功");
    }

    //删除文章
    @Transactional
    @Override
    public R deleteArticle(List<Integer> ids) {
        articlesMapper.deleteBatchIds(ids);
        return R.ok().message("删除成功");
    }

    //修改文章
    @Override
    public R modifyArticle(ArticleVos articleVos) {
        LambdaQueryWrapper<Articles> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Articles::getId, articleVos.getId());
        Articles articles = new Articles();
        BeanUtils.copyProperties(articleVos, articles);
        articles.setUpdateTime(new Date());
        articlesMapper.update(articles, queryWrapper);
        //使用MQ来发送延迟消息  同步es
        rocketMQTemplate.syncSend("article-edit-topic", MessageBuilder.withPayload(articles.getId()).build(), 3600000, 3);
        return R.ok().message("修改成功");
    }

    //获取文章信息
    @Override
    public R getArticleDetails(Long id) {
        Articles articles = articlesMapper.selectById(id);
        User user = userClient.getUserinfoByIdToOtherServe(Long.valueOf(articles.getUserId()));
        //设置作者
        articles.setUser(user);
        //标签翻译
        List<String> labels = labelTranslation(articles.getLabel());
        articles.setLabels(labels);
        //内容等级翻译
        articles.setGradeTranslation(ArticleGrade.find(articles.getGrade()).getDesc());
        return R.ok().data("article", articles);
    }

    //查询当前用户是否点赞或收藏了文章
    @Override
    public R getUserIsLikeOrCollectArticle(int articleId, int userId) {
        Map<String, Integer> map = new HashMap<>();
        QueryWrapper<GiveALike> giveALikeQueryWrapper = new QueryWrapper<>();
        giveALikeQueryWrapper.eq("article_id", articleId).eq("user_id", userId);
        GiveALike giveALike = giveALikeMapper.selectOne(giveALikeQueryWrapper);
        if (giveALike != null) {
            map.put("isLike", giveALike.getIsLike());
        } else {
            map.put("isLike", 0);
        }
        QueryWrapper<Collect> collectQueryWrapper = new QueryWrapper<>();
        collectQueryWrapper.eq("article_id", articleId).eq("user_id", userId);
        Collect collect = collectMapper.selectOne(collectQueryWrapper);
        if (collect != null) {
            map.put("isCollect", collect.getIsCollect());
        } else {
            map.put("isCollect", 0);
        }
        return R.ok().data("map", map);
    }

    //获取当前用户发布的文章
    @Override
    public R getUserArticleList(Long userId) {
        QueryWrapper<Articles> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        List<Articles> articlesList = articlesMapper.selectList(wrapper);
        for (Articles articles : articlesList) {
            articles.setLabels(Arrays.asList(articles.getLabelTranslation().split(",")));
        }
        return R.ok().data("list", articlesList);
    }

    //获取所有文章
    @Override
    public List<Articles> getArticleListToES() {
        List<Articles> articlesList = articlesMapper.selectList(null);
        for (Articles articles : articlesList) {
            User user = userClient.getUserinfoByIdToOtherServe(Long.valueOf(articles.getUserId()));
            //设置作者
            articles.setUser(user);
            //内容等级翻译
            articles.setGradeTranslation(ArticleGrade.find(articles.getGrade()).getDesc());
        }
        return articlesList;
    }

    //查询文章（提供给其他服务）
    @Override
    public Articles getArticleToOther(Long id) {
        Articles articles = articlesMapper.selectById(id);
        User user = userClient.getUserinfoByIdToOtherServe(Long.valueOf(articles.getUserId()));
        //设置作者
        articles.setUser(user);
        //内容等级翻译
        articles.setGradeTranslation(ArticleGrade.find(articles.getGrade()).getDesc());
        return articles;
    }

    //用户修改头像或昵称 es同步
    @Override
    public List<Articles> getUserArticleListToES(Long userId) {
        QueryWrapper<Articles> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        List<Articles> articlesList = articlesMapper.selectList(wrapper);
        for (Articles articles : articlesList) {
            User user = userClient.getUserinfoByIdToOtherServe(Long.valueOf(articles.getUserId()));
            //设置作者
            articles.setUser(user);
            //内容等级翻译
            articles.setGradeTranslation(ArticleGrade.find(articles.getGrade()).getDesc());
        }
        return articlesList;
    }

    //获取浏览量最多的十篇文章
    @Override
    public R getTopTenArticle() {
        QueryWrapper<Articles> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("views").last("limit 10");
        List<Articles> list = articlesMapper.selectList(wrapper);
        return R.ok().data("list", list);
    }

    //搜索
    @Override
    public R searchArticle(ArticleParams articleParams) {
        QueryWrapper<Articles> wrapper = new QueryWrapper<>();
        if (StringUtils.isNoneBlank(articleParams.getTitle())) {
            wrapper.like("title", articleParams.getTitle());
        }
        if (articleParams.getGrade() != null) {
            wrapper.eq("grade", articleParams.getGrade());
        }
        if (articleParams.getStartTime() != null && !"".equals(articleParams.getStartTime())) {
            wrapper.ge("create_time", articleParams.getStartTime());
        }
        if (articleParams.getEndTime() != null && !"".equals(articleParams.getEndTime())) {
            wrapper.le("create_time", articleParams.getEndTime());
        }
        List<Articles> list = articlesMapper.selectList(wrapper);
        return R.ok().data("list", list);
    }

    @Override
    public void exportArticle(HttpServletResponse response) {
        List<Articles> list = articlesMapper.selectList(null);
        ExcelUtils.export(response, "文章信息", Articles.class, list);
    }

    //标签翻译
    private List<String> labelTranslation(String s) {
        List<String> ids = TypeConversion.stringToList(s);
        List<String> labels = new ArrayList<>();
        for (String articleId : ids) {
            TwoSort twoSort = twoSortMapper.selectById(articleId);
            twoSort.setUsageCount(twoSort.getUsageCount() + 1);
            twoSortMapper.updateById(twoSort);
            labels.add(twoSort.getTagName());
        }
        return labels;
    }
}
